package com.atguigu.exam.service.impl;


import com.atguigu.exam.common.Enum.PaperStatus;
import com.atguigu.exam.entity.ExamRecord;
import com.atguigu.exam.entity.Paper;
import com.atguigu.exam.entity.PaperQuestion;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.exception.ExamException;
import com.atguigu.exam.mapper.ExamRecordMapper;
import com.atguigu.exam.mapper.PaperMapper;
import com.atguigu.exam.mapper.PaperQuestionMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.PaperQuestionService;
import com.atguigu.exam.service.PaperService;
import com.atguigu.exam.vo.AiPaperVo;
import com.atguigu.exam.vo.PaperVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 试卷服务实现类
 */
@Slf4j
@Service
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements PaperService {
    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private PaperMapper paperMapper;
    @Autowired
    private PaperQuestionMapper paperQuestionMapper;
    @Autowired
    private PaperQuestionService paperQuestionService;
    @Autowired
    private ExamRecordMapper examRecordMapper;

    /**
     * 获取所有试卷列表（支持模糊搜索和状态筛选）
     */
    public List<Paper> listPapers(String name, String status) {
        LambdaQueryWrapper<Paper> lqw = new LambdaQueryWrapper<>();
        lqw.like(StringUtils.hasText(name), Paper::getName, name);
        lqw.eq(StringUtils.hasText(status), Paper::getStatus, status);
        return list(lqw);
    }

    /**
     * 根据试卷id获取试卷详情（包含题目）
     */
    public Paper getDetailById(Integer id) {
        return baseMapper.getDetailsById(id);
//        Paper paper = getById(id);
//        if (paper == null) {
//            throw new RuntimeException("试卷不存在");
//        }
//        //根据试卷id查找 题目id集合
//        List<Integer> questionIds = paperMapper.getPaperQuestionIds(id);
////        判断questionsIds是不是空
//        if (questionIds != null && questionIds.size() > 0) {
//            //      根据题目id查找相应的题目信息及其选项信息
//            List<Question> questions = new ArrayList<>();
//            questionIds.stream().forEach(questionId -> {
//                Question question = questionMapper.getQuestionById(Long.valueOf(questionId));
////                判断question是不是空
//                if (question != null) {
//                    questions.add(question);
//                }
//            });
//
//            questions.sort((o1, o2) ->
//                    Integer.compare(typeToInt(o1.getType()), typeToInt(o2.getType())));
//            paper.setQuestions(questions);
//            return paper;
//        } else {
//            log.info("没有题目");
//            throw new RuntimeException("这张试卷没有题目");
//        }
    }

    //    给题目集合进行排序,按选择题 判断题 简答题  顺序排序,虽然没啥用,因为前端又进行了一次排序是按创建时间排序的.
    private int typeToInt(String type) {
        switch (type) {
            case "CHOICE":
                return 1; // 选择题
            case "JUDGE":
                return 2;  // 判断题
            case "TEXT":
                return 3;   // 简答题
            default:
                return 4;       // 其他类型
        }
    }

    /**
     * 手动创建试卷
     */
    @Transactional
    public Boolean createPaper(PaperVo paperVo) {
//        判断试卷是否存在
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Paper>().eq(Paper::getName, paperVo.getName()));
        if (exists) {
            throw new ExamException(1002, "试卷已存在");
        }
//        创建试卷对象paper
        Paper paper = new Paper();
        BeanUtils.copyProperties(paperVo, paper);
//        设置试卷当前装填为草稿
        paper.setStatus(PaperStatus.DRAFT.name());
//        获取试卷题目Id 和分数  组成的map集合
        Map<Integer, BigDecimal> questions = paperVo.getQuestions();
//        计算试卷题目当前总分
        BigDecimal reduce = questions.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        paper.setTotalScore(reduce);
//        试卷题目数量
        paper.setQuestionCount(questions.size());
        //保存试卷
        baseMapper.insert(paper);
        //将 questions  转化为List<PaperQuestion>
        List<PaperQuestion> paperQuestionList = questions.entrySet().stream().map(
                entry -> {
                    PaperQuestion paperQuestion
                            = new PaperQuestion(Math.toIntExact(paper.getId()), Long.valueOf(entry.getKey().toString()), entry.getValue());
                    return paperQuestion;
                }
        ).collect(Collectors.toList());
        boolean b = paperQuestionMapper.saveList(paperQuestionList);
        return b;
    }
    /**
     * AI智能组卷（新版）
     * @param aiPaperVo
     * @return
     */
    public Boolean createPaperWithAI(AiPaperVo aiPaperVo){
        return null;
    }
    /**
     * 更新试卷
     * @param id 试卷ID
     * @param paperVo 试卷更新数据
     * @return 操作结果
     */
    public Boolean updatePaper(Integer id, PaperVo paperVo){
        Paper paper = getById(id);
        // 检查试卷状态是不是发布   和 试卷的名字是否存在是否存在
        if (PaperStatus.PUBLISHED.name().equals(paper.getStatus())){
            throw new ExamException(1003, "该试卷正在发布，不能修改");
        }
        LambdaQueryWrapper<Paper> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Paper::getName, paperVo.getName());
        lqw.ne(Paper::getId, id);
        long count = count(lqw);
        if (count > 0){
            throw new ExamException(1002, "试卷已存在");
        }
//        试卷主体
        BeanUtils.copyProperties(paperVo, paper);
//        获取长度
        int length = paperVo.getQuestions().size();
        paper.setQuestionCount(length);
//        将分数总和得到
        BigDecimal reduce = paperVo.getQuestions().values()
                .stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        paper.setTotalScore(reduce);
//        修改paper表
        updateById(paper);
//        中间表,需要先删除原有的联系,然后在绑定现有的联系
        paperQuestionMapper.delete(
                new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId, paper.getId()));
        List<PaperQuestion> paperQuestions = paperVo.getQuestions().entrySet().stream().map(
                entry -> {
                    PaperQuestion paperQuestion = new PaperQuestion(Math.toIntExact(paper.getId()), Long.valueOf(entry.getKey().toString()), entry.getValue());
                    return paperQuestion;
                }
        ).collect(Collectors.toList());
        Boolean b = paperQuestionService.saveBatch(paperQuestions);
        return b;
    }

    /**
     * 更新试卷状态（发布/停止）
     * @param id 试卷ID
     * @param status 新的状态
     * @return 操作结果
     */
    public Boolean updatePaperStatus(Integer id, String status){
        LambdaUpdateWrapper<Paper> luw = new LambdaUpdateWrapper<>();
        luw.eq(Paper::getId, id);
        luw.set(Paper::getStatus, status);
        return update(luw);
    }
    /**
     * 删除试卷
     * @param id 试卷ID
     * @return 操作结果
     */
    @Transactional
    public Boolean customRemoveId(Integer id){
        Paper paper = getById(id);
        if (paper == null || PaperStatus.PUBLISHED.name().equals(paper.getStatus())){
            throw new ExamException(1003, "该试卷正在发布，不能删除");
        }
        LambdaQueryWrapper<ExamRecord> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ExamRecord::getExamId, id);
        Long l = examRecordMapper.selectCount(lqw);
        if (l > 0){
            throw new ExamException(1003, "该试卷正在使用，不能删除");
        }
        boolean b = removeById(Long.valueOf(id));
        int i = paperQuestionMapper.delete(
                new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId, id));
        return i > 0;
    }
}